package com.goalias.controller;

import cn.hutool.core.math.MathUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import com.goalias.resp.BasicResponse;
import com.goalias.resp.HealthResponse;
import com.goalias.resp.SqlResponse;
import com.goalias.resp.WebUriResponse;
import com.goalias.resp.Result;
import com.goalias.utils.BigDecimalUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/user/monitor")
public class MonitorController {

    @Value("${server.port}")
    private String port;

    @Value("${spring.datasource.druid.stat-view-servlet.login-username}")
    private String loginUsername;

    @Value("${spring.datasource.druid.stat-view-servlet.login-password}")
    private String loginPassword;

    private final String javaDate = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

    @GetMapping("/sql")
    public Result sqlMonitor() {
        String response = getMonitor("sql");
        JSONObject responseJson = new JSONObject(response);
        if (responseJson.get("ResultCode",Integer.class) != 1){
            return Result.error("获取sql监控数据失败");
        }
        List<SqlResponse> sqlResponseList = responseJson.getBeanList("Content", SqlResponse.class);
        return Result.success(sqlResponseList);
    }

    @GetMapping("/webUri")
    public Result webUriMonitor() {
        String response = getMonitor("weburi");
        JSONObject responseJson = new JSONObject(response);
        if (responseJson.get("ResultCode",Integer.class) != 1){
            return Result.error("获取weburi监控数据失败");
        }
        List<WebUriResponse> webUriResponseList = responseJson.getBeanList("Content", WebUriResponse.class);
        return Result.success(webUriResponseList);
    }

    @GetMapping("/basic")
    public Result basicMonitor() {
        String response = HttpUtil.get("http://127.0.0.1:" + port + "/actuator/info");
        JSONObject responseJson = new JSONObject(response);
        String version = responseJson.getStr("version");
        String JavaVMName = responseJson.getStr("JavaVMName");
        String javaVMVersion = responseJson.getStr("JavaVMVersion");
        String mysqlDriver = responseJson.getStr("mysqlDriver");
        String mysqlVersion = responseJson.getStr("mysqlVersion");
        String redisVersion = responseJson.getStr("redisVersion");
        BasicResponse basicResponse = BasicResponse.builder()
                .JavaVersion(version)
                .JavaVMName(JavaVMName)
                .StartTime(javaDate)
                .JavaVMVersion(javaVMVersion)
                .mysqlDriver(mysqlDriver)
                .mysqlVersion(mysqlVersion)
                .redisVersion(redisVersion)
                .build();
        return Result.success(basicResponse);
    }

    @GetMapping("/health")
    public Result healthMonitor() {
        String response = HttpUtil.get("http://127.0.0.1:" + port + "/actuator/health");
        JSONObject responseJson = new JSONObject(response);
        String status = responseJson.getStr("status");
        String dbStatus = responseJson.getByPath("components.db.status",String.class);
        String nacosStatus = responseJson.getByPath("components.nacosDiscovery.status",String.class);
        List<String> upServices = responseJson.getByPath("components.discoveryComposite.components.discoveryClient.details.services",List.class);
        String diskSpaceStatus = responseJson.getByPath("components.diskSpace.status",String.class);
        String diskSpaceTotal = responseJson.getByPath("components.diskSpace.details.total",String.class);
        String diskSpaceFree = responseJson.getByPath("components.diskSpace.details.free",String.class);
        String redisStatus = responseJson.getByPath("components.redis.status",String.class);
        HealthResponse healthResponse = HealthResponse.builder()
                .status(status)
                .dbStatus(dbStatus)
                .nacosStatus(nacosStatus)
                .upServices(upServices)
                .diskSpaceStatus(diskSpaceStatus)
                .diskSpaceTotal(Long.parseLong(diskSpaceTotal))
                .diskSpaceFree(Long.parseLong(diskSpaceFree))
                .redisStatus(redisStatus)
                .build();
        String jvmMemoryMax = "jvm.memory.max";
        String jvmMemoryMaxJson = HttpUtil.get("http://127.0.0.1:" + port + "/actuator/metrics/" + jvmMemoryMax);
        JSONObject jvmMemoryMaxResp = new JSONObject(jvmMemoryMaxJson);
        if (jvmMemoryMax.equals(jvmMemoryMaxResp.getStr("name"))){
            Long max = jvmMemoryMaxResp.getJSONArray("measurements").getJSONObject(0).getLong("value");
            healthResponse.setJvmMemoryMax(max);
        }
        String jvmMemoryUsed = "jvm.memory.used";
        String jvmMemoryUsedJson = HttpUtil.get("http://127.0.0.1:" + port + "/actuator/metrics/" + jvmMemoryUsed);
        JSONObject jvmMemoryUsedResp = new JSONObject(jvmMemoryUsedJson);
        if (jvmMemoryUsed.equals(jvmMemoryUsedResp.getStr("name"))){
            Long used = jvmMemoryUsedResp.getJSONArray("measurements").getJSONObject(0).getLong("value");
            healthResponse.setJvmMemoryUsed(used);
        }
        String systemCpuUsage = "system.cpu.usage";
        String systemCpuUsageJson = HttpUtil.get("http://127.0.0.1:" + port + "/actuator/metrics/" + systemCpuUsage);
        JSONObject systemCpuUsageResp = new JSONObject(systemCpuUsageJson);
        if (systemCpuUsage.equals(systemCpuUsageResp.getStr("name"))){
            String cpuUsedStr = systemCpuUsageResp.getJSONArray("measurements").getJSONObject(0).getStr("value");
            String cpuUsed = String.format("%.3f", Double.parseDouble(cpuUsedStr));
            healthResponse.setSystemCpuUsage(cpuUsed);
        }
        return Result.success(healthResponse);
    }



    private String getMonitor(String type) {
        Map<String, Object> requestParams = new HashMap<>();
        requestParams.put("loginUsername", loginUsername);
        requestParams.put("loginPassword", loginPassword);
        return HttpUtil.get("http://127.0.0.1:" + port + "/druid/"+type+".json", requestParams);
    }
}
